/**
 * src/composables/useApi.js
 * ✅ 支持 GET / POST / PUT / DELETE
 * ✅ 支持分页、动态 URL、请求防抖
 * ✅ 支持自动请求 / 手动请求
 * ✅ 支持自动重试、Token 过期处理
 * ✅ 支持 toast 成功/失败提示（可选）
 * ✅ 自动 loading 状态管理
 * ✅ 支持响应数据 transform 处理函数
 * 使用场景示例：
 * 1、GET请求（自动发起）
    const { loading, result, error } = useApi({
      url: '/users',
      method: 'get',
      transform: res => res.users, // 取接口 data 里 users 字段
    })
    // result.value 就是 users 数组，自动请求，无需手动调用

 * 2、POST请求（登陆场景，异步请求）
    const username = ref('')
    const password = ref('')

    const { loading, error, fetchData } = useApi({
      url: '/auth/login',
      method: 'post',
      manual: true,
    })

    async function login() {
      await fetchData({
        data: {
          username: username.value,
          password: password.value,
        },
      })
      // 这里可以处理响应，或者 useApi 里自定义 transform
    }

 * 3、PUT 请求更新数据
    const { loading, error, fetchData } = useApi({
      url: '/profile/update',
      method: 'put',
      manual: true,
    })

    function updateProfile(newData) {
      fetchData({ data: newData })
    }

 * 4、DELETE 请求，动态 URL
    const { loading, error, fetchData } = useApi({
      url: '', // 空，url 动态传入
      method: 'delete',
      manual: true,
    })

    function deleteItem(id) {
      fetchData({ url: `/items/${id}` })
    }

 * 5、分页请求
    const { loading, result, error, currentPage, totalPages, fetchData } = useApi({
      url: '/posts',
      method: 'get',
      pagination: true,
      transform: res => res.data,
    })

    // 切换页码
    function goPage(page) {
      currentPage.value = page
      fetchData()
    }

 * 6、请求防抖（搜索框）
    const keyword = ref('')

    const { loading, result, fetchData } = useApi({
      url: '/search',
      method: 'get',
      params: { keyword: keyword.value },
      manual: true,
      debounceDelay: 500, // 500ms 防抖
    })

    // 监听关键词变化，调用fetchData
    watch(keyword, (newVal) => {
      fetchData({ params: { keyword: newVal } })
    })

 * 7、自动重试失败请求
    const { loading, result, error } = useApi({
      url: '/data',
      method: 'get',
      autoRetry: true,
    })
  
 */

import { ref, watchEffect } from 'vue';
import axios from '../api/axios'; // 你项目里的 axios 实例
import { useToast } from './useToast'; // 你写的 toast 组合函数
import { useAuthStore } from '../store/auth'; // Pinia 认证状态管理

// 防抖工具函数，避免请求频繁触发
function debounce(fn, delay = 300) {
    let timer = null;
    return (...args) => {
        clearTimeout(timer);
        timer = setTimeout(() => {
            fn(...args);
        }, delay);
    };
}

/**
 * 通用请求组合函数，封装了请求发起、状态管理、错误处理等逻辑
 * @param {Object} config - 配置对象
 * @param {string} config.url - 请求地址，支持动态传入
 * @param {string} [config.method='get'] - 请求方法
 * @param {Object} [config.params=null] - URL 查询参数(GET 请求用)
 * @param {Object} [config.data=null] - 请求体数据(POST/PUT 请求用)
 * @param {boolean} [config.manual=false] - 是否手动触发请求
 * @param {boolean} [config.immediate=true] - 是否初始化时自动请求
 * @param {boolean} [config.autoRetry=false] - 请求失败时是否自动重试
 * @param {boolean} [config.pagination=false] - 是否分页请求
 * @param {Function} [config.transform=res=>res] - 响应数据转换函数
 * @param {number} [config.debounceDelay=0] - 请求防抖延迟(ms)，0为关闭
 * @param {boolean} [config.toast=true] - 是否自动弹出错误提示
 * @returns {Object} 包含响应状态和请求触发函数
 */
export function useApi(config) {
    // 解构并设置默认值
    const {
        url = '',
        method = 'get',
        params = null,
        data = null,
        manual = false,
        immediate = true,
        autoRetry = false,
        pagination = false,
        transform = res => res,
        debounceDelay = 0,
        toast = true
    } = config;

    // 响应式状态
    const loading = ref(false); // 请求是否进行中
    const error = ref(null); // 请求错误信息
    const response = ref(null); // axios 原始响应
    const result = ref(null); // 处理后的数据，给业务用
    const currentPage = ref(1); // 当前页，分页请求时使用
    const totalPages = ref(1); // 总页数，分页请求时使用

    // 状态管理和toast
    const auth = useAuthStore();
    const { error: showError } = useToast();

    /**
     * 获取服务器返回的错误信息
     * @param {Object} err - 错误对象
     * @returns {string} 错误信息
     */
    const getServerMessage = err => {
        return err.response?.data?.msg || err.response?.data?.message;
    };

    /**
     * 处理HTTP错误状态码
     * @param {Object} err - 错误对象
     */
    const handleHttpError = err => {
        const serverMessage = getServerMessage(err);

        // 401 处理，清理 token 并提示登录
        if (err.response?.status === 401) {
            auth.clearToken();
            toast && showError(serverMessage || '登录状态已失效，请重新登录');
        } else if (err.response?.status === 403) {
            // 403 权限错误提示
            toast && showError(serverMessage || '您没有权限访问该资源，请联系管理员');
        } else if (err.response?.status === 404) {
            // 404 未找到提示
            toast && showError(serverMessage || '请求的资源未找到，请检查 URL 是否正确');
        } else {
            // 其他错误弹提示
            toast && showError(serverMessage || err?.message || '网络异常，请联系管理人员');
        }
    };

    /**
     * 合并请求参数
     * @param {Object} override - 覆盖参数
     * @returns {Object} 合并后的参数
     */
    const mergeParams = (override = {}) => {
        const baseParams = typeof params === 'function' ? params() : params;

        if (pagination) {
            return {
                ...baseParams,
                ...override.params,
                page: currentPage.value
            };
        }

        return {
            ...baseParams,
            ...override.params
        };
    };

    // 发送请求的内部函数，支持动态覆盖参数
    const _fetch = async (override = {}) => {
        loading.value = true;
        error.value = null;

        try {
            // 合并传入参数，分页加上 page
            const finalParams = mergeParams(override);

            // 发起请求
            const res = await axios.request({
                method: override.method || method,
                url: override.url || url, // 如果 override.url 是“真值”（truthy），就用 override.url
                params: finalParams,
                data: override.data ?? data // 如果 override.data 不是 null 或 undefined，就用 override.data
            });

            response.value = res;
            // 经过转换函数处理数据
            result.value = transform(res.data);

            // 如果分页，更新总页数，字段名根据后端而定
            if (pagination && res.data?.total_pages) {
                totalPages.value = res.data.total_pages;
            }

            // 返回响应数据，以便调用者可以访问
            return res;

            // 异常捕获
        } catch (err) {
            error.value = err;

            // 处理HTTP错误状态码
            handleHttpError(err);

            // 自动重试，延迟2秒后再次发请求
            if (autoRetry) {
                setTimeout(() => _fetch(override), 2000);
            }

            // 重新抛出错误，以便调用者可以处理
            throw err;
        } finally {
            loading.value = false;
        }
    };

    // 支持防抖的请求触发函数，外部调用
    const fetchData = debounceDelay > 0 ? debounce(args => _fetch(args), debounceDelay) : _fetch;

    // 自动请求逻辑
    if (immediate && !manual) {
        watchEffect(() => {
            fetchData();
        });
    }

    return {
        loading,
        error,
        response,
        result,
        currentPage,
        totalPages,
        fetchData // 手动触发请求
    };
}
